package org.bluedream.core.module.service.clsItem;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.bluedream.comm.utils.EmptyUtil;
import org.bluedream.comm.utils.RestResult;
import org.bluedream.core.module.base.OrgTreeServiceImpl;
import org.bluedream.core.module.dao.clsItem.ClsItemDao;
import org.bluedream.core.module.entity.clsItem.ClsItem;
import org.bluedream.core.module.sys.service.OrganizationService;
import org.bluedream.core.module.sys.service.org.OrgRelationService;
import org.bluedream.core.utils.UserUtil;
import org.bluedream.core.utils.configUtil.GoalConfigUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName ClsItemService
 * @Description TODO
 * @Author foxsand
 * @Data 2021/4/23 11:21
 * @Version
 */
@Service
@DS("master")
@Transactional(readOnly = true)
public class ClsItemService extends OrgTreeServiceImpl<ClsItemDao , ClsItem> implements IService<ClsItem> {
    private static final Logger logger = LoggerFactory.getLogger(ClsItemService.class);

    /**
     * 获取树结构数据
     * @param excludeCode 排除的code
     * @param isShowCode 是否显示编码（true or 1：显示在左侧；2：显示在右侧；false or null：不显示）
     * @return
     */
    public List<Map<String , Object>> treeData(String excludeCode , String isShowCode){
        return super.treeData(excludeCode , isShowCode , new ClsItem());
    }

    @Override
    @Transactional(
            readOnly = false,
            rollbackFor = Exception.class
    )
    public boolean save(ClsItem entity) {
        UserUtil.allowSystemNodeSave();
        boolean flag;
        try {
            Map<String , String> newRecordSearchMap = new HashMap<>();
            newRecordSearchMap.put("code" , "getTreeCode");
            newRecordSearchMap.put("org_code" , "getOrgCode");
            super.setIsNewRecord(entity , newRecordSearchMap);
            entity.setLimitTreeLevel(true);
            entity.setMaxTreeLevel(Integer.parseInt(GoalConfigUtil.getValueByKey("sys.cls.level")));
            flag = super.save(entity);

            if (!flag){
                return false;
            }

            QueryWrapper<ClsItem> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.eq("code" , entity.getTreeCode());
            entity = super.getOne(entity , newRecordSearchMap);

            /**
             * 从参数配置信息中获取品类最大级别，如果
             */
            int maxTreeLevel = Integer.parseInt(GoalConfigUtil.getValueByKey("sys.cls.level"));
            int treeLevel = entity.getTreeLevel() + 1;
            if (maxTreeLevel != treeLevel){
                entity.setTreeLeaf("0");
                flag = super.updateById(entity);
            }

            return flag;
        }catch (Exception e){
            e.printStackTrace();
            logger.error("保存品类信息失败，错误信息：" + e.getMessage());
            //todo:@Transactional和try catch捕获异常会让注解失效
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return false;
    }

    @Transactional(
            readOnly = false,
            rollbackFor = Exception.class
    )
    public RestResult excelImport(List<ClsItem> list){
        try{
            for (ClsItem c1:list
                 ) {
                String clsCode = c1.getTreeCode();
                QueryWrapper<ClsItem> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("code" , clsCode);
                queryWrapper.eq("org_code" , UserUtil.getLoginOrgCode());
                ClsItem t1 = super.getOne(queryWrapper);
                if (EmptyUtil.isNoEmpty(t1)){
                    c1.setIsNewRecord(false);
                }else {
                    String parentCode = c1.getTreeCode().substring(0 , 3*(c1.getTreeCode().length()/3 - 1));
                    QueryWrapper<ClsItem> q1 = new QueryWrapper<>();
                    q1.eq("code" , parentCode);
                    q1.eq("org_code" , UserUtil.getLoginOrgCode());
                    ClsItem pClsItem = super.getOne(q1);
                    c1.setParent(pClsItem);
                    c1.setIsNewRecord(true);
                    c1.initParentParameter();
                    c1.initTreeParameter();
                    int _sort = super.getDefaultTreeSort(c1 , "code" , "tree_sorts" , "tree_sort");
                    c1.setTreeSort(_sort);
                    c1.setTreeSorts();
                }
                save(c1);
            }
        }catch (Exception e1){
            e1.printStackTrace();
            logger.error(e1.getMessage());
            //todo:@Transactional和try catch捕获异常会让注解失效
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RestResult.error("数据保存失败:" + e1.getMessage());
        }
        return RestResult.ok();
    }

    @Override
    public ClsItem getById(Serializable id) {
        if (EmptyUtil.isEmpty(id)){
            return new ClsItem();
        }else {
            ClsItem clsItem = super.getById(id);
            if (!"0".equals(clsItem.getParentCode())){
                clsItem.setParent(super.getById(clsItem.getParentCode()));
            }
            return clsItem;
        }
    }

    @Override
    public ClsItem createNextNode(ClsItem entity , String... lastChildrenNodeOrderArgs) {
        entity = super.createNextNode(entity , lastChildrenNodeOrderArgs);
        return entity;
    }

    public IPage<ClsItem> findPage(ClsItem entity){
        return super.findPage(entity , null , "tree_Sorts" , "tree_Sort");
    }
}
